/*
 Copyright 2011, Lucid Technics, LLC.

 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
 except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in
 writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 specific language governing permissions and limitations under the License.
*/

package airlift.generator;

import org.antlr.stringtemplate.StringTemplate;

import javax.lang.model.element.Element;
import java.util.Iterator;
import java.util.Map;

// TODO: Auto-generated Javadoc
/**
 * The Class LuceneGenerator.
 */
public class LuceneGenerator
   extends Generator
{
	
	/** The comment. */
	public String comment = "This code has been generated by airlift. Do not modify this code. Instead, you may extend this class with your own concrete implementation located under src/java.";

	/* (non-Javadoc)
	 * @see airlift.generator.Generator#generate(java.lang.String, java.lang.String, javax.lang.model.element.Element, airlift.generator.DomainObjectModel, java.util.Map)
	 */
	public void generate(String _appName,
				String _directory,
				Element _element,
				DomainObjectModel _domainObjectModel,
				Map<String, DomainObjectModel> _elementNameToDomainObjectModelMap)
	{
	    String generatedString = generateSearcher(_domainObjectModel);
	    String fileName =  _directory + "." + _domainObjectModel.getRootPackageName() + ".airlift.search." + _domainObjectModel.getClassName() + "Searcher";
		writeJavaFile(fileName, generatedString, _element);
	}
	
	/**
	 * Generate searcher.
	 *
	 * @param _domainObjectModel the _domain object model
	 * @return the string
	 */
	public String generateSearcher(DomainObjectModel _domainObjectModel)
	{	    
		StringTemplate searcherStringTemplate = getStringTemplateGroup().getInstanceOf("hannibal/search/lucene/Searcher");

	    Iterator attributes = _domainObjectModel.getAttributes();
		
	    while (attributes.hasNext() == true)
		{
			StringTemplate indexFieldFragmentStringTemplate = getStringTemplateGroup().getInstanceOf("hannibal/search/lucene/IndexFieldFragment");
			StringTemplate queryFragmentStringTemplate = getStringTemplateGroup().getInstanceOf("hannibal/search/lucene/QueryFragment");
			
			Attribute attribute = (Attribute) attributes.next();
			Annotation search = (Annotation) _domainObjectModel.getAnnotation(attribute,"airlift.generator.Searchable");
			Annotation persist = (Annotation) _domainObjectModel.getAnnotation(attribute,"airlift.generator.Persistable");
			
			String requestPersistence = findValue(persist, "isPersistable()");
			String requestSearch = findValue(search, "isSearchable()");

			String isPrimaryKey = "false";
			
			if ("true".equals(requestPersistence) == true)
			{
				isPrimaryKey = findValue(persist, "isPrimaryKey()");
			}

			if ("true".equals(requestSearch) == true || "true".equalsIgnoreCase(isPrimaryKey) == true)
			{
				String type = attribute.getType();
				String name = attribute.getName();

				queryFragmentStringTemplate.setAttribute("className", upperTheFirstCharacter(_domainObjectModel.getClassName()));
				queryFragmentStringTemplate.setAttribute("attributeName", name);
				
				indexFieldFragmentStringTemplate.setAttribute("className", upperTheFirstCharacter(_domainObjectModel.getClassName()));
				indexFieldFragmentStringTemplate.setAttribute("lowercaseClassName", lowerTheFirstCharacter(_domainObjectModel.getClassName()));
				indexFieldFragmentStringTemplate.setAttribute("attributeName", name);
				indexFieldFragmentStringTemplate.setAttribute("uppercaseAttributeName", upperTheFirstCharacter(name));
				
				String indexable = findValue(search, "indexable()");
				String storable = findValue(search, "storable()");
				String tokenizable = findValue(search, "tokenizable()");

				if("true".equalsIgnoreCase(isPrimaryKey) == true || "true".equalsIgnoreCase(storable) == true)
				{
					indexFieldFragmentStringTemplate.setAttribute("store", "Store.YES");
				}
				else
				{
					indexFieldFragmentStringTemplate.setAttribute("store", "Store.NO");
				}
				
				if ("true".equals(indexable) == true || "true".equalsIgnoreCase(isPrimaryKey) == true)
				{
					indexFieldFragmentStringTemplate.setAttribute("index", "Index.ANALYZED");
				}
				else
				{
					indexFieldFragmentStringTemplate.setAttribute("index", "Index.NO");
				}
				
				String analyzerString = "new StandardAnalyzer()" ;

				indexFieldFragmentStringTemplate.setAttribute("fieldAnalyzer", analyzerString);

				searcherStringTemplate.setAttribute("indexFieldFragment", indexFieldFragmentStringTemplate);
				searcherStringTemplate.setAttribute("queryFragment", queryFragmentStringTemplate);
			}
		}
		
	    searcherStringTemplate.setAttribute("generatorComment", comment);
	    searcherStringTemplate.setAttribute("package", _domainObjectModel.getRootPackageName());
	    searcherStringTemplate.setAttribute("fullClassName", _domainObjectModel.getPackageName() + "." + _domainObjectModel.getClassName());
		searcherStringTemplate.setAttribute("className", upperTheFirstCharacter(_domainObjectModel.getClassName()));
		searcherStringTemplate.setAttribute("lowercaseClassName", lowerTheFirstCharacter(_domainObjectModel.getClassName()));

	    return searcherStringTemplate.toString();
	}

	/**
	 * Generate searcher factory.
	 *
	 * @param _rootPackageName the _root package name
	 * @return the string
	 */
	public String generateSearcherFactory(String _rootPackageName)
	{
		StringTemplate stringTemplate = getStringTemplateGroup().getInstanceOf("hannibal/search/lucene/SearcherFactory");

		stringTemplate.setAttribute("package", _rootPackageName);
		stringTemplate.setAttribute("generatorComment", comment);

		return stringTemplate.toString();
	}
}